

/**
 * 原型链继承：简单易实现，无法向父类构造函数传参，引用属性被所有实例共享
 */
// function Person() {
//   this.names = ['妖怪','小妖怪','大伟'];
// }

// function Student() {
//   this.age = 19; 
// }

// Person.prototype.sayHello = function() {
//     console.log('sayHello')
// }

// Student.prototype = new Person();
// const stu = new Student();
// const stu1 = new Student();
// stu.names.push('假妖怪');
// console.log('stu',stu.names);
// console.log('stu1',stu1.names);

/**
 * 构造函数继承：解决引用属性共享问题，可向父类传参，但是无法继承父类原型上的方法，方法都在构造函数中定义，无法复用
 */

// function Person(names) {
//   this.names = names;
// }

// function Student(names,age) {
//   Person.call(this,names) 
//   this.age = age;
// }

// Person.prototype.sayHello = function() {
//     console.log('sayHello')
// }

// const stu = new Student(['大伟','小伟'],20);
// const stu1 = new Student(['伟','妖怪'],18);
// console.log('stu',stu.names);
// console.log('stu1',stu1.names);


/**
 * 
 * 组合继承：实际上是原型链继承和构造函数继承结合，实例属性不共享，可继承原型方法，可向父类传参，但是调用了两次父构造函数 
 */
// function Person(names) {
//   this.names = names;
// }

// function Student(names,age) {
//   Person.call(this,names) 
//   this.age = age;
// }

// Person.prototype.sayHello = function() {
//     console.log('sayHello')
// }

// Student.prototype = new Person();
// // 修复构造器的指向
// Student.prototype.constructor = Student;
// const stu = new Student(['大伟','小伟'],20);
// const stu1 = new Student(['伟','妖怪'],18);
// console.log('stu',stu);
// console.log('stu1',stu1);
// console.log(stu1.constructor === Student)


/**
 * 寄生组合继承：不直接修改原来的对象，而是创建原来对象的副本
 * 
 * 
 */
// function Person(names) {
//   this.names = names;
// }



// Person.prototype.sayHello = function() {
//     console.log(this.names[0]+ ' sayHello')
// }

// function Student(names,age) {
//   Person.call(this,names) 
//   this.age = age;
// }

// Student.prototype.sayHi = function () {
//   console.log('sayHi')
// }

// Student.prototype = Object.create(Person.prototype); // 这是寄生组合继承的关键
// Student.prototype.constructor = Student; // 一定要记得修复construtor的指向
// const stu = new Student(['大伟','小伟'],20);
// const stu1 = new Student(['伟','妖怪'],18);
// console.log('stu',stu);
// console.log('stu1',stu1);

/**
 * es6 class继承：语法简洁,旧浏览器需要转译
 */

class Person {
  constructor(names) {
    this.names = names;
  }

  sayHello() {
    console.log(this.names[0]+ ' sayHello')
  }

}

class Student extends Person {
  constructor(names,age) {
    super(names);
    this.age = age;
  }

  sayHi() {
    console.log('sayHi')
  }
}

const stu = new Student(['大伟','小伟'],20)
const stu1 = new Student(['小伟'],18)
stu.sayHello();
stu1.sayHello();
console.log('stu',stu);
console.log('stu1',stu1);